package com.ruoyi.deeplearn.service.impl;

import java.util.Date;
import java.util.List;

import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.deeplearn.component.ModelDeployComponent;
import com.ruoyi.deeplearn.component.ModelForecastComponent;
import com.ruoyi.deeplearn.domain.*;
import com.ruoyi.deeplearn.mapper.*;
import com.ruoyi.deeplearn.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 模型Service业务层处理
 *
 * @author 任伟伟
 * @date 2022-12-10
 */
@Service
public class DeepModelServiceImpl implements IDeepModelService
{
    @Autowired
    private DeepAlgorithmMapper deepAlgorithmMapper;
    @Autowired
    private DeepModelMapper deepModelMapper;
    @Autowired
    private DeepModelVersionMapper deepModelVersionMapper;
    @Autowired
    private DeepModelDeployMapper deepModelDeployMapper;
    @Autowired
    private DeepForecastMapper deepForecastMapper;
    @Autowired
    private ModelForecastComponent modelForecastComponent;
    @Autowired
    private ModelDeployComponent modelDeployComponent;
    @Autowired
    private IDeepModelTrainService deepModelTrainService;
    @Autowired
    private IDeepModelDatasetService deepModelDatasetService;
    @Autowired
    private IDeepModelVersionService deepModelVersionService;

    @Autowired
    private IDeepModuleNetService deepModuleNetService;

    /**
     * 查询模型
     *
     * @param id 模型主键
     * @return 模型
     */
    @Override
    public DeepModel selectDeepModelById(Long id)
    {
        return deepModelMapper.selectDeepModelById(id);
    }

    /**
     * 查询模型列表
     *
     * @param deepModel 模型
     * @return 模型
     */
    @Override
    public List<DeepModel> selectDeepModelList(DeepModel deepModel)
    {
        return deepModelMapper.selectDeepModelList(deepModel);
    }

    /**
     * 新增模型
     *
     * @param deepModel 模型
     * @return 结果
     */
    @Override
    public int insertDeepModel(DeepModel deepModel)
    {
        deepModel.setId(IdUtil.getSnowflakeNextId());
        deepModel.setCreateTime(DateUtils.getNowDate());
        int result = deepModelMapper.insertDeepModel(deepModel);
        return result;
    }

    /**
     * 修改模型
     *
     * @param deepModel 模型
     * @return 结果
     */
    @Override
    public int updateDeepModel(DeepModel deepModel)
    {
        deepModel.setUpdateTime(DateUtils.getNowDate());
        return deepModelMapper.updateDeepModel(deepModel);
    }

    /**
     * 批量删除模型
     *
     * @param ids 需要删除的模型主键
     * @return 结果
     */
    @Override
    public int deleteDeepModelByIds(Long[] ids)
    {
        return deepModelMapper.deleteDeepModelByIds(ids);
    }

    /**
     * 删除模型信息
     *
     * @param id 模型主键
     * @return 结果
     */
    @Override
    public int deleteDeepModelById(Long id)
    {
        return deepModelMapper.deleteDeepModelById(id);
    }

    @Override
    public int addNewVersion(NewModelVersionVo newModelVersionVo) {
        DeepModelVersion versionVo = newModelVersionVo.getModel();
        if(versionVo ==null)return 0;
        DeepModelDataset datasetVo = newModelVersionVo.getDataset();
        if(datasetVo ==null)return 0;
        DeepModelTrain trainVo = newModelVersionVo.getTrain();
        if(trainVo ==null)return 0;
        DeepModel deepModel = selectDeepModelById(newModelVersionVo.getModelId());
        if(deepModel==null)return 0;
        DeepModuleNet moduleNet = deepModuleNetService.
                selectDeepModuleNetById(versionVo.getModuleNetId());
        if(moduleNet==null)return 0;
        DeepModelVersion version = new DeepModelVersion();
        version.setVersion(versionVo.getVersion());
        version.setModuleId(deepModel.getModuleId());
        version.setModelId(deepModel.getId());
        version.setModuleNetId(versionVo.getModuleNetId());
        if(DeepModuleNet.type_import_net.equals(moduleNet.getConfigType())){
            version.setTrainStatus(DeepModelVersion.trainStatus_trained);
            version.setDeployStatus(DeepModelVersion.deployStatus_not_deployed);
        }else if(DeepModuleNet.type_external_service.equals(moduleNet.getConfigType())){
            version.setTrainStatus(DeepModelVersion.trainStatus_trained);
            version.setDeployStatus(DeepModelVersion.deployStatus_deployed);
        }else {
            version.setTrainStatus(DeepModelVersion.trainStatus_not_trained);
            version.setDeployStatus(DeepModelVersion.deployStatus_not_deployed);
        }
        deepModelVersionService.insertDeepModelVersion(version);
        if(DeepModuleNet.type_import_net.equals(moduleNet.getModuleType())
                ||DeepModuleNet.type_external_service.equals(moduleNet.getModuleType())){
            DeepModelDataset dataset = new DeepModelDataset();
            deepModelDatasetService.insertDeepModelDataset(dataset);
        }
        if(trainVo!=null){
            trainVo.setModelId(version.getModelId());
            trainVo.setModelVersionId(version.getId());
            deepModelTrainService.insertDeepModelTrain(trainVo);
        }
        deepModel.setCurrentVersionId(version.getId());
        deepModel.setCurrentVersionCode(version.getVersion());
        deepModel.setModuleNetId(version.getModuleNetId());
        updateDeepModel(deepModel);
        return 1;
    }

    @Override
    public DeepModel selectDeepModelByCode(String code) {
        return deepModelMapper.selectDeepModelByCode(code);
    }

    //////////////////////////一下代码废弃了/////////////////////////////////
    @Override
    public int addModelTrain(ModelTrainVo modelTrainVo) {
        DeepModel deepModel = deepModelMapper.selectDeepModelById(modelTrainVo.getModelId());
        if(deepModel==null)return 0;
        DeepAlgorithm deepAlgorithm = deepAlgorithmMapper.
                selectDeepAlgorithmById(modelTrainVo.getTrainAlgorithmId());
        if(deepAlgorithm==null)return 0;
        DeepModelVersion modelVersion = new DeepModelVersion();
        modelVersion.setId(IdUtil.getSnowflakeNextId());
        modelVersion.setModelId(deepModel.getId());
        if(deepModel.getCurrentVersionId()==null){
            modelVersion.setVersion(1);
        }else {
            DeepModelVersion preVersion = deepModelVersionMapper.
                    selectDeepModelVersionById(deepModel.getCurrentVersionId());
            if(preVersion!=null){
                modelVersion.setVersion(preVersion.getVersion()+1);
            }else {
                modelVersion.setVersion(1);
            }
        }
        modelVersion.setDeployStatus(0);
        deepModelVersionMapper.insertDeepModelVersion(modelVersion);
        deepModel.setCurrentVersionId(modelVersion.getId());
        deepModelMapper.updateDeepModel(deepModel);
        return 1;
    }

    @Override
    public int addModelDeploy(ModelDeployVo modelDeployVo) {
        DeepModel deepModel = deepModelMapper.selectDeepModelById(modelDeployVo.getModelId());
        if(deepModel==null)return 0;
        DeepModelVersion modelVersion = deepModelVersionMapper.selectDeepModelVersionById(modelDeployVo.getModelVersionId());
        if(modelVersion==null)return 0;
        DeepModelDeploy modelDeploy = new DeepModelDeploy();
        modelDeploy.setId(IdUtil.getSnowflakeNextId());
        modelDeploy.setStatus(1);
        modelDeploy.setModelId(deepModel.getId());
        modelDeploy.setModelVersionId(modelVersion.getId());
        modelDeploy.setServiceUrl(modelDeployVo.getServiceUrl());
        modelDeploy.setRemark(modelDeployVo.getRemark());
        deepModelDeployMapper.insertDeepModelDeploy(modelDeploy);
        modelVersion.setDeployId(modelDeploy.getId());
        deepModelVersionMapper.updateDeepModelVersion(modelVersion);
        //执行部署
        modelDeployComponent.publishDeploy(modelDeploy.getId());
        return 1;
    }

    @Override
    public int addModelForecast(ModelForecastVo modelForecastVo) {
        if(modelForecastVo.getModelVersionId()==null
                ||modelForecastVo.getFiles()==null||modelForecastVo.getFiles().size()==0)return 0;
        DeepModelVersion modelVersion = deepModelVersionMapper.selectDeepModelVersionById(modelForecastVo.getModelVersionId());
        if(modelVersion==null)return 0;
        DeepModel deepModel = deepModelMapper.selectDeepModelById(modelVersion.getModelId());
        if(deepModel==null)return 0;
        DeepModelDeploy modelDeploy = deepModelDeployMapper.
                selectDeepModelDeployById(modelVersion.getDeployId());
        if(modelDeploy==null)return 0;
        modelForecastVo.getFiles().stream().forEach(minioFile -> {
            DeepForecast forecast = new DeepForecast();
            forecast.setId(IdUtil.getSnowflakeNextId());
            forecast.setModelId(deepModel.getId());
            forecast.setModelVersionId(modelVersion.getId());
            forecast.setDeployId(modelDeploy.getId());
            forecast.setUrl(minioFile.getUrl());
            forecast.setFileName(minioFile.getFileName());
            forecast.setFileExt(minioFile.getFileExt());
            forecast.setFileSize(minioFile.getFileSize());
            forecast.setBucket(minioFile.getBucket());
            forecast.setObjectName(minioFile.getObjectName());
            forecast.setStatus(0);
            forecast.setStartTime(new Date());
            deepForecastMapper.insertDeepForecast(forecast);
            //添加到预测队列
            modelForecastComponent.publishForecast(forecast.getId());
        });
        return modelForecastVo.getFiles().size();
    }

    @Override
    public int addModelForecastByForecastId(Long forecastId) {
        modelForecastComponent.publishForecast(forecastId);
        return 1;
    }
    ////////////////////////////////////////////////////////////
}
